package org.academik.controller;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import org.academik.model.Anioescolar;
import org.academik.model.Catalogoservicios;
import org.academik.model.Detallerecibo;
import org.academik.model.DetallereciboId;
import org.academik.model.Lugtrabajo;
import org.academik.model.Matricula;
import org.academik.model.Persona;
import org.academik.model.Recibo;
import org.academik.model.Seccion;
import org.academik.util.FacesUtil;
import org.academik.util.HibernateUtil;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.StatelessSession;
import org.hibernate.Transaction;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.primefaces.event.SelectEvent;
import org.primefaces.event.DateSelectEvent;

/**
 *
 * @author Javier
 */
@ManagedBean(name = "consultaMatriculaBean")
@ViewScoped
public class ConsultaMatriculaBean extends AbstractViewScopedBean implements Serializable {

    /** Declaracion de Variables*/
    private ArrayList<Object[]> listaMatricula;
    private Object[] selectedMatricula;
    private Matricula matricula;
    private String buscarResponsable;
    private Persona responsable;
    private Lugtrabajo lugarTrabResponsable;
    private Recibo recibo;
    private Long selectedSeccion;
    private Long selectedSeccionConsulta;
    private ArrayList<Object[]> arregloDetalles;
    private double totalPagar;
    private Detallerecibo detalleRecibo;
    private String url;
    private Long selectedConcepto;
    private String detalleConcepto;
    private Object[] selectedPago;
    private Date fechaConsulta = null;
    private Long selectedAnio;
    private boolean showAddDetalle;

    /** Creates a new instance of ConsultaMatriculaBean */
    public ConsultaMatriculaBean() {
        this.nuevo();
    }

    @Override
    public void crear() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void eliminar() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void cargarOpciones() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void cargarOpciones(int id) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void buscar() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void modificar() {
        Session session = HibernateUtil.getSessionFactory().openSession();
        this.responsable = new Persona();
        this.recibo = new Recibo();
        this.matricula = new Matricula();
        this.selectedSeccion = null;
        this.buscarResponsable = null;
        Criteria cMatricula = session.createCriteria(Matricula.class);
        cMatricula.add(Restrictions.eq("idMatricula", Long.valueOf(selectedMatricula[6].toString())));
        this.matricula = (Matricula) cMatricula.uniqueResult();

        Criteria cResponsable = session.createCriteria(Persona.class);
        cResponsable.add(Restrictions.eq("idPersona", Long.valueOf(selectedMatricula[11].toString())));
        this.responsable = (Persona) cResponsable.uniqueResult();

        Criteria cRecibo = session.createCriteria(Recibo.class);
        cRecibo.add(Restrictions.eq("idRecibo", Long.valueOf(selectedMatricula[7].toString())));
        this.recibo = (Recibo) cRecibo.uniqueResult();
        this.selectedSeccion = this.matricula.getSeccion().getIdSeccion();
        session.close();
        this.cargarPago(); //Cargar pago cada vez que de clic en el lapiz
    }

    @Override
    public void cargarResgistros() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void nuevo() {
        this.listaMatricula = new ArrayList<Object[]>();
        this.selectedMatricula = null;
        this.matricula = new Matricula();
        this.buscarResponsable = null;
        this.responsable = null;
        this.lugarTrabResponsable = new Lugtrabajo();
        this.recibo = new Recibo();
        this.selectedSeccion = null;
        this.arregloDetalles = new ArrayList<Object[]>();
        this.totalPagar = 0;
        this.detalleRecibo = new Detallerecibo();
        this.url = null;
        this.selectedConcepto = null;
        this.detalleConcepto = null;
        this.selectedPago = null;
        anioEscolar tempAnio = new anioEscolar();
        this.selectedAnio = tempAnio.anioLectivo().getIdAnioEscolar();
        this.populateListaMatricula();
        this.showAddDetalle = false;
    }

    /** Cargar Datos en la Tabla de la Vista de la Tabla de la BD*/
    public void populateListaMatricula() {
        this.listaMatricula = new ArrayList<Object[]>();
        StatelessSession session = HibernateUtil.getSessionFactory().openStatelessSession();
        String sql = "SELECT DATE_FORMAT(m.daFechMatricula,'%d-%m-%Y %h:%i %p'), " //0
                + "CONCAT_WS(' ', g.vcNomGrado, s.vcSeccion), " //1
                + "(SELECT CONCAT_WS(' ' , pa.vcNombres, pa.vcApellidos) FROM persona pa WHERE pa.idPersona = a.persona_idPersona), " //2
                + "CONCAT_WS(' ' , p.vcNombres, p.vcApellidos), " //3
                + "r.nuNumRecibo, " //4
                + "m.alumno_idAlumno, " //5
                + "m.idMatricula, " //6 
                + "r.idRecibo, " //7 
                + "s.idSeccion, " //8
                + "g.idGrado, " //9
                + "n.idNivel, " //10
                + "p.idPersona " // 11
                + "FROM "
                + "matricula m INNER JOIN alumno a ON a.idAlumno = m.alumno_idAlumno "
                + "INNER JOIN persona p ON m.persona_idPersona = p.idPersona "
                + "INNER JOIN recibo r ON m.recibo_idRecibo = r.idRecibo "
                + "INNER JOIN seccion s ON m.seccion_idSeccion = s.idSeccion "
                + "INNER JOIN grado g ON s.grado_idgrado = g.idGrado "
                + "INNER JOIN nivel n ON g.nivel_idNivel = n.idNivel "
                + "INNER JOIN anioescolar an ON s.anioescolar_idAnioEscolar = an.idAnioEscolar ";
        if (this.selectedSeccionConsulta != null || this.fechaConsulta != null || this.selectedAnio != null) {
            sql = sql + "WHERE ";
        }
        if (this.selectedSeccionConsulta != null) {
            sql = sql + "s.idSeccion = :idSeccion ";
        }
        if (this.selectedSeccionConsulta != null && this.fechaConsulta != null) {
            sql = sql + "AND ";
        }
        if (this.fechaConsulta != null) {
            sql = sql + "DATE(m.daFechMatricula) = DATE(:fecha) ";
        }
        if (this.selectedSeccionConsulta != null || this.fechaConsulta != null) {
            sql = sql + "AND ";
        }
        if (this.selectedAnio != null) {
            sql = sql + "an.idAnioEscolar = :idAnio ";
        }
        sql = sql + "ORDER BY DATE(m.daFechMatricula) DESC, r.nuNumRecibo DESC ";
        Query query = session.createSQLQuery(sql);
        //query.setMaxResults(100);
        if (this.fechaConsulta != null) {
            query.setParameter("fecha", this.fechaConsulta);
        }
        if (this.selectedSeccionConsulta != null) {
            query.setParameter("idSeccion", this.selectedSeccionConsulta);
        }
        if (this.selectedAnio != null) {
            query.setParameter("idAnio", this.selectedAnio);
        }
        this.listaMatricula = (ArrayList<Object[]>) query.list();
        session.close();
    }

    public void mostrarTodo() {
        this.selectedSeccionConsulta = null;
        this.fechaConsulta = null;
        anioEscolar tempAnio = new anioEscolar();
        this.selectedAnio = tempAnio.anioLectivo().getIdAnioEscolar();
        this.populateListaMatricula();
    }

    /** Convierte Date a String*/
    public String getStringDate(Date d) {
        if (d == null) {
            return "";
        }
        return FacesUtil.getStringDate(d);
    }

    /** Eliminar Matricula*/
    public void eliminarMatricula() {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = null;
        this.matricula = new Matricula();
        Matricula s = (Matricula) session.load(Matricula.class, Long.valueOf(selectedMatricula[6].toString()));
        try {
            tx = (Transaction) session.beginTransaction();
            session.delete(s);
            tx.commit();
            this.nuevo();
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Información:", "Registro eliminado satisfactoriamente"));
        } catch (HibernateException e) {
            tx.rollback();
            FacesUtil.hibernateException(e);
        } finally {
            session.close();
        }
    }

    /*Metodo para el autoComplete*/
    public void onSelectNomPadre(SelectEvent event) {
        this.onKeyPress();
    }

    /**Cargar datos en los formularios una vez se seleccione el nombre del campo de tipo autocomplete*/
    private void onKeyPress() {
        Session session = HibernateUtil.getSessionFactory().openSession();
        String sql = "SELECT p FROM Persona p "
                + "WHERE CONCAT_WS(' ',p.vcNombres,p.vcApellidos) "
                + "LIKE :valor AND (p.boPadre = TRUE OR p.boResponsable = TRUE)";
        Query query = session.createQuery(sql);
        query.setParameter("valor", "%" + this.buscarResponsable + "%");
        query.setMaxResults(1);
        if (query.uniqueResult() != null) {
            this.responsable = (Persona) query.uniqueResult();
            Iterator iterLugTrabajo = this.responsable.getLugtrabajos().iterator();
            if (iterLugTrabajo.hasNext()) {
                this.lugarTrabResponsable = (Lugtrabajo) iterLugTrabajo.next();
            }
        }
        session.close();
    }

    /** Cargar Secciones en el formato Grado Seccion*/
    public ArrayList<SelectItem> cargarSecciones() {
        Session session = HibernateUtil.getSessionFactory().openSession();
        ArrayList<SelectItem> lista = new ArrayList<SelectItem>();

        Criteria cSeccion = session.createCriteria(Seccion.class);
        cSeccion.add(Restrictions.eq("anioescolar", this.anioLectivo()));
        Iterator iter = cSeccion.list().iterator();

        while (iter.hasNext()) {
            Seccion s = (Seccion) iter.next();
            lista.add(new SelectItem(s.getIdSeccion(), s.getGrado().getVcNomGrado() + " " + s.getVcSeccion(), ""));
        }
        if (!lista.isEmpty()) {
            this.selectedSeccion = (Long) lista.get(0).getValue();
        }
        session.close();
        return lista;
    }

    /** Cargar Conceptos en el campo concepto*/
    public ArrayList<SelectItem> cargarConceptos() {
        Session session = HibernateUtil.getSessionFactory().openSession();
        ArrayList<SelectItem> lista = new ArrayList<SelectItem>();

        Criteria cCatalogo = session.createCriteria(Catalogoservicios.class);
        Iterator iter = cCatalogo.list().iterator();

        while (iter.hasNext()) {
            Catalogoservicios s = (Catalogoservicios) iter.next();
            lista.add(new SelectItem(s.getIdCatalogoServicios(), s.getVcConceptoServicio(), ""));
        }
        session.close();
        return lista;
    }

    /** Extraer que año se encuentra como lectivo en la BD*/
    public Anioescolar anioLectivo() {
        Anioescolar tempAnio = new Anioescolar();
        Session session = HibernateUtil.getSessionFactory().openSession();
        Criteria cAnioLectivo = session.createCriteria(Anioescolar.class);
        cAnioLectivo.add(Restrictions.eq("boEstado", true));
        tempAnio = (Anioescolar) cAnioLectivo.uniqueResult();
        session.close();
        return tempAnio;
    }

    //Aqui para mostrar los datos de los pagos pero en el frmConsultaMatricula
    public void cargarPago() {
        Recibo tempRecibo = new Recibo();
        Session session = HibernateUtil.getSessionFactory().openSession();
        tempRecibo = (Recibo) session.load(Recibo.class, Long.valueOf(selectedMatricula[7].toString()));
        String sql = "SELECT dr FROM Detallerecibo dr "
                + "JOIN dr.recibo r "
                + "WHERE dr.recibo = :parametro";
        Query query = session.createQuery(sql);
        query.setParameter("parametro", tempRecibo);

        if (this.arregloDetalles.isEmpty()) {
            Iterator iter = query.list().iterator();
            while (iter.hasNext()) {
                Detallerecibo tempDetalle = (Detallerecibo) iter.next();

                Object[] objPago = new Object[3];
                objPago[0] = tempDetalle.getCatalogoservicios().getVcConceptoServicio();
                objPago[1] = tempDetalle;
                objPago[2] = tempDetalle.getCatalogoservicios().getIdCatalogoServicios();

                this.totalPagar += tempDetalle.getNuPrecio() * tempDetalle.getNuCantidad();
                this.arregloDetalles.add(objPago);
            }
        }
        session.close();
        this.selectedMatricula = null;
    }

    /** Metodo Imprimir para los recibos*/
    public void imprimir() {
        String contextPath = FacesContext.getCurrentInstance().getExternalContext().getRequestContextPath();
        this.url = contextPath + "/faces/createReportServlet?fileName=";
        String fileName = "reciboSA";
        String tipo = "application/pdf";
        String params = "&tipo=" + tipo + "&idMatricula=" + this.selectedMatricula[6].toString();
        this.url = this.url + fileName + params;
    }

    /** Agregar Pagos*/
    public void addDetallesRecibo() {
        Object[] objPago = new Object[3];
        objPago[0] = this.detalleConcepto;
        objPago[1] = this.detalleRecibo;
        objPago[2] = this.selectedConcepto;
        this.totalPagar += this.detalleRecibo.getNuPrecio() * this.detalleRecibo.getNuCantidad();
        this.arregloDetalles.add(objPago);
        this.vaciarPagos();
    }

    /** Vaciar variables de detalles pagos*/
    public void vaciarPagos() {
        this.detalleRecibo = new Detallerecibo();
        this.detalleConcepto = null;
        this.selectedConcepto = null;
        this.showAddDetalle = false;
    }

    /** Cuando seleccione un concepto actualice el concepto*/
    public void onChangeConcepto() {
        if (this.selectedConcepto != null) {
            Session session = HibernateUtil.getSessionFactory().openSession();
            Criteria cCatalogo = session.createCriteria(Catalogoservicios.class);
            cCatalogo.add(Restrictions.eq("idCatalogoServicios", this.selectedConcepto));
            Catalogoservicios cs = (Catalogoservicios) cCatalogo.uniqueResult();
            this.detalleRecibo.setCatalogoservicios(cs);
            this.detalleRecibo.setNuPrecio(cs.getNuPrecioDefault());
            this.detalleConcepto = cs.getVcConceptoServicio();
            session.close();
            this.showAddDetalle = true;
        } else {
            this.vaciarPagos();
        }
    }

    /** Remover detalles pago*/
    public void removeDetalles() {
        this.detalleRecibo = (Detallerecibo) this.selectedPago[1];
        this.arregloDetalles.remove(this.selectedPago);
        this.totalPagar -= this.detalleRecibo.getNuPrecio() * this.detalleRecibo.getNuCantidad();
        this.selectedPago = null;
        this.detalleRecibo = new Detallerecibo();
        this.detalleConcepto = null;
    }

    /** Confirmar modificaciones en la matricula*/
    public void confirmarModificacion() {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = null;
        try {
            tx = (Transaction) session.beginTransaction();
            Recibo tempRecibo = (Recibo) session.load(Recibo.class, this.recibo.getIdRecibo());
            tempRecibo.setNuNumRecibo(this.recibo.getNuNumRecibo());

            //Inicio Modificacion para almacenar el recibo modificado y el detalle del recibo para frmConsultaMatricula
            tempRecibo.setNuCantidadDeuda(this.recibo.getNuCantidadDeuda());
            tempRecibo.setBoPendientePago(false);
            if (this.recibo.getNuCantidadDeuda() > 0) {
                tempRecibo.setBoPendientePago(true);
            }
            session.update(tempRecibo);

            //Como es modificacion elimine datos viejos del detellarecibo
            String sql = "DELETE FROM detallerecibo "
                    + "WHERE recibo_idRecibo = :id";
            Query query = session.createSQLQuery(sql);
            query.setParameter("id", tempRecibo.getIdRecibo());
            query.executeUpdate();

            Iterator iter = this.arregloDetalles.iterator();
            while (iter.hasNext()) { //E ingrese los nuevos detalles al recibo viejo
                Object[] obj = (Object[]) iter.next();
                Detallerecibo detalle = (Detallerecibo) obj[1];
                Long idServicio = (Long) obj[2];

                DetallereciboId idDetalle = new DetallereciboId();
                idDetalle.setReciboIdRecibo(this.recibo.getIdRecibo());
                idDetalle.setCatalogoServiciosIdCatalogoServicios(idServicio);
                detalle.setRecibo(this.recibo);
                detalle.setId(idDetalle);
                session.saveOrUpdate(detalle);
            }
            this.arregloDetalles = new ArrayList<Object[]>();
            this.totalPagar = 0;
            //Fin Modificacion para almacenar el recibo modificado y el detalle del recibo para frmConsultaMatricula

            Seccion tempSeccion = (Seccion) session.load(Seccion.class, this.selectedSeccion);
            this.matricula.setSeccion(tempSeccion);
            this.matricula.setPersona(this.responsable);
            session.update(this.matricula);
            tx.commit();

            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_INFO, "Información:", "La matricula se modifico satisfactoriamente"));
            this.nuevo(); //Inicializa las variables
        } catch (HibernateException e) {
            tx.rollback();
            FacesUtil.hibernateException(e);
        } finally {
            session.close();
        }
    }

    public void handleDateSelect(DateSelectEvent event) {
        this.fechaConsulta = event.getDate();
        this.populateListaMatricula();
    }

    /**
     * Getters & Setters
     */
    public ArrayList<Object[]> getListaMatricula() {
        return listaMatricula;
    }

    public void setListaMatricula(ArrayList<Object[]> listaMatricula) {
        this.listaMatricula = listaMatricula;
    }

    public Object[] getSelectedMatricula() {
        return selectedMatricula;
    }

    public void setSelectedMatricula(Object[] selectedMatricula) {
        this.selectedMatricula = selectedMatricula;
    }

    public String getBuscarResponsable() {
        return buscarResponsable;
    }

    public void setBuscarResponsable(String buscarResponsable) {
        this.buscarResponsable = buscarResponsable;
    }

    public Matricula getMatricula() {
        return matricula;
    }

    public void setMatricula(Matricula matricula) {
        this.matricula = matricula;
    }

    public Persona getResponsable() {
        return responsable;
    }

    public void setResponsable(Persona responsable) {
        this.responsable = responsable;
    }

    public Lugtrabajo getLugarTrabResponsable() {
        return lugarTrabResponsable;
    }

    public void setLugarTrabResponsable(Lugtrabajo lugarTrabResponsable) {
        this.lugarTrabResponsable = lugarTrabResponsable;
    }

    public Recibo getRecibo() {
        return recibo;
    }

    public void setRecibo(Recibo recibo) {
        this.recibo = recibo;
    }

    public Long getSelectedSeccion() {
        return selectedSeccion;
    }

    public void setSelectedSeccion(Long selectedSeccion) {
        this.selectedSeccion = selectedSeccion;
    }

    public ArrayList<Object[]> getArregloDetalles() {
        return arregloDetalles;
    }

    public void setArregloDetalles(ArrayList<Object[]> arregloDetalles) {
        this.arregloDetalles = arregloDetalles;
    }

    public double getTotalPagar() {
        return totalPagar;
    }

    public void setTotalPagar(double totalPagar) {
        this.totalPagar = totalPagar;
    }

    public Detallerecibo getDetalleRecibo() {
        return detalleRecibo;
    }

    public void setDetalleRecibo(Detallerecibo detalleRecibo) {
        this.detalleRecibo = detalleRecibo;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public Long getSelectedConcepto() {
        return selectedConcepto;
    }

    public void setSelectedConcepto(Long selectedConcepto) {
        this.selectedConcepto = selectedConcepto;
    }

    public String getDetalleConcepto() {
        return detalleConcepto;
    }

    public void setDetalleConcepto(String detalleConcepto) {
        this.detalleConcepto = detalleConcepto;
    }

    public Object[] getSelectedPago() {
        return selectedPago;
    }

    public void setSelectedPago(Object[] selectedPago) {
        this.selectedPago = selectedPago;
    }

    public Date getFechaConsulta() {
        return fechaConsulta;
    }

    public void setFechaConsulta(Date fechaConsulta) {
        this.fechaConsulta = fechaConsulta;
    }

    public Long getSelectedSeccionConsulta() {
        return selectedSeccionConsulta;
    }

    public void setSelectedSeccionConsulta(Long selectedSeccionConsulta) {
        this.selectedSeccionConsulta = selectedSeccionConsulta;
    }

    public Long getSelectedAnio() {
        return selectedAnio;
    }

    public void setSelectedAnio(Long selectedAnio) {
        this.selectedAnio = selectedAnio;
    }

    public boolean isShowAddDetalle() {
        return showAddDetalle;
    }

    public void setShowAddDetalle(boolean showAddDetalle) {
        this.showAddDetalle = showAddDetalle;
    }
}
